﻿using SIR.Common.Condition;
using SIR.Entities.Implementations;
using System;
using System.Linq;
using System.Web;

namespace SIR.Web
{
	internal static class SessionManager
	{
		/// <summary>
		/// The name of the cookie on the requests
		/// </summary>
		private const string _cookieName = "SirWebId";
		/// <summary>
		/// Sets the user for a session
		/// </summary>
		/// <param name="httpContext">The current HTTP context</param>
		/// <param name="user"></param>
		internal static void SetSession(System.Web.HttpContext httpContext, User user)
		{
			SirSession session = null;
			// Find the session
			GetSession(httpContext, out session);
			// No session found
			if (session == null)
				return;
			// If the passed user is null, delete the session
			if (user == null)
				session.IsDeleted = true;
			else
				session.UserId = user.Id; // Set the user Id for the session
			// Save the session
			DAL.DataServer.Save<SirSession>(session);
		}
		/// <summary>
		/// Gets the session for the HTTP context
		/// </summary>
		/// <param name="httpContext">The current HTTP context</param>
		/// <param name="session">Outputs the session object</param>
		/// <param name="createIfNotFound">Indicates wether or not the session is should be created if not found, default true</param>
		private static void GetSession(System.Web.HttpContext httpContext, out SirSession session, bool createIfNotFound = true)
		{
			HttpCookie sessionCookie = null;
			// Gets the cookie from the session
			sessionCookie = httpContext.Request.Cookies.Get(_cookieName);
			// If the cookies was found and has a value
			if (sessionCookie != null && !string.IsNullOrWhiteSpace(sessionCookie.Value))
			{
				// Set the cookie to expire in 10 minutes
				sessionCookie.Expires = DateTime.Now.AddMinutes(10.0);
				// Add the cookie to the response
				httpContext.Response.SetCookie(sessionCookie);
				// Find the session object
				session = DAL.DataServer.Find<SirSession>(new Predicate("SessionId", sessionCookie.Value, PredicateOperator.EqualTo)).Results.FirstOrDefault();
				// If the session was found and has a user Id, then done
				if (session != null && session.UserId >= 0)
					return;
			}

			// If do not create a session, clear the found session and return
			if (!createIfNotFound)
			{
				session = null;
				return;
			}

			// Create a new session Id
			var sessionId = Guid.NewGuid().ToString();
			// Create the cookie
			sessionCookie = new HttpCookie(_cookieName, sessionId);
			// Set the expiration
			sessionCookie.Expires = DateTime.Now.AddMinutes(10.0);
			// Save the session
			session = new SirSession();
			session.SessionId = sessionId;
			session = DAL.DataServer.Save<SirSession>(session).NewValue;
			// Add the cookie to the response
			httpContext.Response.Cookies.Add(sessionCookie);
		}

		/// <summary>
		/// Gets the session for the user from the HTTP context
		/// </summary>
		/// <param name="httpContext">The current HTTP context</param>
		/// <param name="userId">Outputs the identifier for the user if the session is found</param>
		/// <param name="createIfNotFound">True to create the session if the session is not found</param>
		internal static void GetSession(System.Web.HttpContext httpContext, out long? userId, bool createIfNotFound = true)
		{
			SirSession session = null;
			// Get the session from the context
			GetSession(httpContext, out session, createIfNotFound);
			// Set the user id if the session is found
			userId = session == null ? null : (long?)session.UserId;
		}
	}
}